package com.ruoyi.business.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.ruoyi.business.domain.HistoricActivity;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IProcessService;
import com.ruoyi.business.service.IServiceItemService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.CarPackageAuditMapper;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 审核列表Service业务层处理
 * 
 * @author wolfcode
 * @date 2021-07-20
 */
@Service
public class CarPackageAuditServiceImpl implements ICarPackageAuditService
{
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;
    @Autowired
    private IProcessService processService;
    @Autowired
    private IServiceItemService serviceItemService;
    @Autowired
    private IDefinitionNodeService definitionNodeService;
    @Autowired
    private ISysUserService sysUserService;

    /**
     * 查询审核列表
     * 
     * @param id 审核列表ID
     * @return 审核列表
     */
    @Override
    public CarPackageAudit selectCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.selectCarPackageAuditById(id);
    }

    /**
     * 查询审核列表列表
     * 
     * @param carPackageAudit 审核列表
     * @return 审核列表
     */
    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit)
    {
        List<CarPackageAudit> carPackageAudits = carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
        for (CarPackageAudit packageAudit : carPackageAudits) {
            //将快照的JSON格式转换为对象
            ServiceItem serviceItem = JSON.parseObject(packageAudit.getServiceItemInfo(), ServiceItem.class);
            packageAudit.setServiceItem(serviceItem);
            //通过实例id获取当前任务节点
            Task currentTask = processService.selectTaskByProcessInstanceId(packageAudit.getInstanceId());
            //判断任务是否为空(任务是否完成)
            if(currentTask != null) {
                packageAudit.setTaskId(currentTask.getId());
                packageAudit.setTaskName(currentTask.getName());
            }else {
                packageAudit.setTaskName("任务结束");
            }
        }
        return carPackageAudits;
    }

    /**
     * 新增审核列表
     * 
     * @param carPackageAudit 审核列表
     * @return 结果
     */
    @Override
    public int insertCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        carPackageAudit.setCreateTime(DateUtils.getNowDate());
        return carPackageAuditMapper.insertCarPackageAudit(carPackageAudit);
    }

    /**
     * 修改审核列表
     * 
     * @param carPackageAudit 审核列表
     * @return 结果
     */
    @Override
    public int updateCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        return carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    /**
     * 删除审核列表对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditByIds(String ids)
    {
        return carPackageAuditMapper.deleteCarPackageAuditByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除审核列表信息
     * 
     * @param id 审核列表ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.deleteCarPackageAuditById(id);
    }

    /**
     * 审核撤销
     * @param instanceId
     * @param carPackageAuditId
     */
    @Override
    @Transactional
    public void cancelApply(String instanceId, Long carPackageAuditId) {
        //根据流程实例id获取流程实例对象
        ProcessInstance processInstance = processService.getProcessInstanceByInstanceId(instanceId);

        //修改审核列表对象并设置到表中:审核状态为审核撤销,审核人为空,当前任务为空
        //获取审核对象
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(carPackageAuditId);
        carPackageAudit.setStatus(CarPackageAudit.STATUS_CANCEL);
        carPackageAudit.setAuditors("");
        carPackageAudit.setTaskName("");
        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);

        //修改服务项目表:审核状态
        ServiceItem serviceItem = JSON.parseObject(carPackageAudit.getServiceItemInfo(), ServiceItem.class);
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        serviceItemService.updateServiceItemNoCondition(serviceItem);

        //删除流程实例
        processService.deleteProcessInstanceByInstanceId(processInstance.getProcessInstanceId());
    }

    /**
     * 查询待办
     * @param carPackageAudit
     * @return
     */
    @Override
    public List<CarPackageAudit> selectTodoList(CarPackageAudit carPackageAudit) {
        //查询当前登陆用户的待办任务总数
        long count = processService.selectTodoTaskCount(CarPackageAudit.DEFINITION_KEY, ShiroUtils.getUserId().toString());

        //判断是否大于0,如果大于0表示有待办任务,如果等于0表示没有待办任务,则返回空集合
        if(count > 0 ){
            //activiti不支持分页插件pageHelper,需要手写分页
            //获取前台传入的pageNum和PageSize
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();

            //查询当前登陆用户的待办任务的集合
            List<Task> taskList = processService.selectTodoTaskList(
                    CarPackageAudit.DEFINITION_KEY,    //流程定义key
                    ShiroUtils.getUserId().toString(), //当前登陆用户
                    (pageNum-1)*pageSize,   //开始条数
                    pageSize); //一页显示多少条


            //遍历待办任务,查询对应的CarPackageAudit对象
            ArrayList<CarPackageAudit> resultList = new ArrayList<>();
            CarPackageAudit audit;
            for (Task task : taskList) {
                //通过任务的实例id获取流程实例对象
                ProcessInstance processInstance = processService.selectProcessInstanceByProcessInstanceId(task.getProcessInstanceId());

                //通过流程实例对象获取通过businesskey
                String businessKey = processInstance.getBusinessKey();

                //通过businesskey查找对应的CarPackageAudit对象
                audit = carPackageAuditMapper.selectCarPackageAuditById(Long.valueOf(businessKey));

                //将CarPackageAudit的JSON格式的ServiceItemInfo转换为ServiceItem对象,并设置到audit中
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class));

                //设置audit任务名/id
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());

                //存入到resultList中
                resultList.add(audit);
            }

            //封装成Page对象返回,Page继承了ArrayList,所有也是一个集合,其内部封装了分页的功能
            Page<CarPackageAudit> list = new Page<>();
            list.setTotal(count);
            list.setPageNum(pageNum);
            list.setPageSize(pageSize);
            list.addAll(resultList);
            return list;
        }else {
            //没有待办任务,返回空集合
            return Collections.EMPTY_LIST;
        }
    }

    /**
     * 处理任务
     * @param taskId
     * @param auditStatus
     * @param comment
     */
    @Override
    @Transactional
    public void complete(String taskId, Boolean auditStatus, String comment) {

        //获取任务
        Task task = processService.selectTaskByTaskId(taskId);
        //获取流程实例
        ProcessInstance processInstance = processService.selectProcessInstanceByProcessInstanceId(task.getProcessInstanceId());

        //领取任务
        //添加批注
        //添加流程变量
        //处理任务
        processService.claimAndComplete(task,ShiroUtils.getUserId(),auditStatus,comment);

        //获取下一个节点nextTask
        Task nextTask = processService.selectTaskByProcessInstanceId(task.getProcessInstanceId());

        //通过业务key查询CarPackageAudit对象,用于之后的逻辑对审核列表对象进行操作或拿取属性
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(Long.valueOf(processInstance.getBusinessKey()));

        //判断流程是否结束(有没有下一个节点nextTask是否为null)
        if(nextTask != null){
            //有下一个节点

            //收集指定候选人姓名
            List<String> auditors = new ArrayList<>();
            if(auditStatus){
                //如果auditStatus(同意或拒绝) = true

                //根据下一个节点的key查询审核人并设置候选人
                List<SysUser> sysUsers = definitionNodeService.selectAuditorsByTaskDefinitionKey(nextTask.getTaskDefinitionKey());
                
                for (SysUser sysUser : sysUsers) {
                    processService.addCandidateUser(nextTask,sysUser.getUserId());
                    auditors.add(sysUser.getUserName());
                }
            }else {
                //如果auditStatus(同意或拒绝) = false

                //将流程发起人设置为节点候选人
                processService.addCandidateUser(nextTask,Long.valueOf(carPackageAudit.getCreateBy()));
                //审核状态修改为审核拒绝1(快照表)
                auditors.add(carPackageAudit.getCreateByName());
                carPackageAudit.setStatus(CarPackageAudit.STATUS_REJECT);

            }
            //将auditors中的审核人名称转换为JSON格式并存入到carPackageAudit中
            carPackageAudit.setAuditors(JSON.toJSONString(auditors));

        }else {
            //没有下一个节点
            //修改 服务项表,快照表 的审核状态
            carPackageAudit.setAuditors("");
            carPackageAudit.setStatus(CarPackageAudit.STATUS_PASS);

            ServiceItem serviceItem = JSON.parseObject(carPackageAudit.getServiceItemInfo(),ServiceItem.class);
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_APPROVED);
            serviceItemService.updateServiceItemNoCondition(serviceItem);
        }

        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);

    }

    /**
     * 重新申请
     * @param taskId
     * @param carPackageAuditId
     */
    @Override
    @Transactional
    public void reApply(String taskId, Long carPackageAuditId) {
        //根据任务id获取任务对象
        Task task = processService.selectTaskByTaskId(taskId);
        //设置新的流程变量
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectCarPackageAuditById(carPackageAuditId);
        //获取服务项
        ServiceItem serviceItem = JSON.parseObject(carPackageAudit.getServiceItemInfo(),ServiceItem.class);
        processService.setVariable(task.getId(),"money",serviceItem.getDiscountPrice().longValue());
        //领取任务
        //处理任务
        processService.claimAndComplete(task,ShiroUtils.getUserId(),"重新申请");
        //获取下一个节点
        Task nextTask = processService.selectTaskByProcessInstanceId(task.getProcessInstanceId());
        //通过节点key查询审核人设置节点候选人
        List<String> auditors_name = new ArrayList<>();
        List<SysUser> sysUsers = definitionNodeService.selectAuditorsByTaskDefinitionKey(nextTask.getTaskDefinitionKey());
        for (SysUser sysUser : sysUsers) {
            processService.addCandidateUser(nextTask,sysUser.getUserId());
            auditors_name.add(sysUser.getUserName());
        }
        //修改快照表:审核人,修改审核状态为审核中
        carPackageAudit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
        carPackageAudit.setAuditors(JSON.toJSONString(auditors_name));
        carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    /**
     * 查询已办审批
     * @param carPackageAudit
     * @return
     */
    @Override
    public List<CarPackageAudit> selectDoneList(CarPackageAudit carPackageAudit) {
        //编写分页查询已办任务

        //查询当前登陆用户的已办任务总数(历史)
        long count = processService.selectDoneTaskCount(CarPackageAudit.DEFINITION_KEY,ShiroUtils.getUserId().toString());

        //当count大于0表示有数据
        if(count > 0) {
            //分页参数
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();
            Integer startNum = (pageNum - 1) * pageSize;
            //查询当前登陆用户的已办任务集合(历史),并传入分页参数
            List<HistoricTaskInstance> taskList =
                    processService.selectDoneTaskList(
                            CarPackageAudit.DEFINITION_KEY,
                            ShiroUtils.getUserId().toString(),
                            startNum,
                            pageSize
                    );

            //遍历集合,设置serviceItem,任务名称/id,结束时间
            List<CarPackageAudit> auditList = new ArrayList<>();
            for (HistoricTaskInstance task : taskList) {
                //获取历史流程实例
                HistoricProcessInstance historicProcessInstance = processService.selectHistoryProcessInstanceById(task.getProcessInstanceId());
                //根据历史流程实例id获取businessKey
                String businessKey = historicProcessInstance.getBusinessKey();
                //根据businessKey获取CarPackageAudit
                CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(Long.valueOf(businessKey));
                //将audit中的ServiceItemInfo转换为对象并设置audit对象中
                ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class);
                audit.setServiceItem(serviceItem);
                //设置任务名/id,结束时间
                audit.setTaskId(task.getId());
                audit.setTaskName(task.getName());
                audit.setDoneTime(task.getEndTime());
                auditList.add(audit);
            }
            //封装到Page中,并返回
            Page<CarPackageAudit> page = new Page<>();
            page.setPageNum(pageNum);
            page.setPageSize(pageSize);
            page.setTotal(count);
            page.addAll(auditList);

            return page;
        }else {
            //当count等于0,表示没有数据,返回空集合
            return Collections.EMPTY_LIST;
        }

    }

    /**
     * 查询历史审批
     * @param instanceId
     * @return
     */
    @Override
    public List<HistoricActivity> selectHistoricActivity(String instanceId) {
        //获取历史活动节点集合
        List<HistoricActivityInstance> instanceList =  processService.selectHistoricActivityInstanceByInstanceId(instanceId);

        List<HistoricActivity> resultList = new ArrayList<>();
        //遍历历史活动节点集合
        for (HistoricActivityInstance instance : instanceList) {
            //将集合元素设置到HistoricActivity对象中
            HistoricActivity historicActivity = new HistoricActivity();

            BeanUtils.copyProperties(instance,historicActivity);

            //通过任务id获取批注,并设置到HistoricActivity对象
            String comment = processService.selectCommentByTaskId(instance.getTaskId());
            historicActivity.setComment(comment);
            //获取审核人id,并判断是否查询审核人名称
            String assignee = instance.getAssignee();
            if(assignee != null){
                SysUser sysUser = sysUserService.selectUserById(Long.valueOf(assignee));
                if(sysUser != null) {
                    historicActivity.setAssigneeName(sysUser.getUserName());
                }
            }
            resultList.add(historicActivity);
        }
        return resultList;
    }

}
